﻿using LPBToolsLib.NetSocket;
using Newtonsoft.Json;
using PLCConsole;
using PLCConsole.PLCConsole;
using PLCConsole.PLCSerStation;
using StationNF;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DExDatasClients_数据展示客户端_
{
    public partial class FDatasClient : Form
    {
        private Dictionary<string, string> lastCommand { get; set; } = new Dictionary<string, string>();
        private Dictionary<string, Dictionary<string, object>> tCommandResult { get; set; } = null;
        public string tCurrentStaID { get; set; } = "";
        public const string Command_GetStationList = "GetStationList";
        public const string Command_GetStationRunInfo = "GetStationRunInfo";
        public FDatasClient()
        {
            InitializeComponent();
        }
        private byte[] getComamndBytes(Dictionary<string, string> tCommand)
        {
            if ((tCommand != null) && (tCommand.Count > 0))
            {
                string sInfo = JsonConvert.SerializeObject(tCommand);
                return Encoding.UTF8.GetBytes(sInfo);
            }
            return null;
        }
        private void buttonGetStationList_Click(object sender, EventArgs e)
        {
            listViewStationList.Items.Clear();
            tCurrentStaID = "";
            tCommandResult = null;
            tPLCStation = null;
            IPEndPoint destEP = new IPEndPoint(IPAddress.Parse(textBoxAPISerIP.Text), (int)numericUpDownAPISerPort.Value);
            lastCommand = new Dictionary<string, string>();
            lastCommand.Add(Command_GetStationList, "");
            byte[] tBuf = getComamndBytes(lastCommand);
            TCPClientAsync.SendWithCallBack(destEP, tBuf, tGetStationsListCallBack, 1000);
        }

        void tGetStationsListCallBack(object sender, byte[] RecData)
        {
            Dictionary<string, object> tRespons = null;
            if ((RecData != null) && (RecData.Length > 0))
            {
                string sInfo = "";
                try
                {
                    sInfo = Encoding.UTF8.GetString(RecData);
                    if ((!string.IsNullOrEmpty(sInfo)) && sInfo.StartsWith("{") && sInfo.EndsWith("}"))
                        tRespons = JsonConvert.DeserializeObject<Dictionary<string, object>>(sInfo);
                }
                catch (Exception ex)
                {
                }
            }
            if ((lastCommand != null) && (lastCommand.Count == 1) && (tRespons != null) && (tRespons.Count > 0))
            {
                if (tRespons.ContainsKey("err") && tRespons.ContainsKey("msg") && tRespons["msg"].Equals("ok")
                    && tRespons["err"].ToString().Equals("0"))
                {
                    string[] tKeys = lastCommand.Keys.ToArray();
                    switch (tKeys[0])
                    {
                        case Command_GetStationList:
                            if (tRespons.ContainsKey("StaInfoList"))
                            {
                                tCommandResult = new Dictionary<string, Dictionary<string, object>>();
                                Dictionary<string, object> tStaInfoTmp = getJSONDictionaryByObject(tRespons["StaInfoList"]);
                                foreach (KeyValuePair<string, object> item in tStaInfoTmp)
                                {
                                    tCommandResult.Add(item.Key, getJSONDictionaryByObject(item.Value));
                                }
                            }
                            break;
                        case Command_GetStationRunInfo:

                            break;
                        default:
                            break;
                    }
                }
            }
        }

        private Dictionary<string, object> getJSONDictionaryByObject(object tJSONObject)
        {
            if (tJSONObject != null)
                try
                {
                    string sStr = tJSONObject.ToString();
                    if ((!string.IsNullOrEmpty(sStr)) && sStr.StartsWith("{") && sStr.EndsWith("}"))
                        return JsonConvert.DeserializeObject<Dictionary<string, object>>(sStr);
                }

                catch (Exception ex)
                {
                }
            return null;
        }

        private void tDeamon_Tick(object sender, EventArgs e)
        {
            if ((lastCommand != null) && (lastCommand.Count == 1) && (tCommandResult != null))
                try
                {
                    string[] tKeys = lastCommand.Keys.ToArray();
                    switch (tKeys[0])
                    {
                        case Command_GetStationList:
                            foreach (KeyValuePair<string, Dictionary<string, object>> item in tCommandResult)
                            {
                                ListViewItem tItem = new ListViewItem(item.Key);
                                int iStationType = -1;

                                string sInfo = "";
                                if (item.Value.ContainsKey("StationType") && int.TryParse(item.Value["StationType"].ToString(), out iStationType)
                                    && (iStationType >= 0))
                                    sInfo = ((StationPLCType)iStationType).ToString() + ":";
                                if (item.Value.ContainsKey("StationRegStar"))
                                    sInfo += item.Value["StationRegStar"].ToString() + ":";
                                if (item.Value.ContainsKey("StationRegCount"))
                                    sInfo += item.Value["StationRegCount"].ToString();
                                tItem.SubItems.Add(sInfo);
                                tItem.Tag = item.Value;
                                listViewStationList.Items.Add(tItem);
                            }
                            break;
                        case Command_GetStationRunInfo:
                            break;
                        default:
                            break;
                    }
                }
                finally
                {
                    lastCommand.Clear();
                    tCommandResult = null;
                }
            if (!string.IsNullOrEmpty(tCurrentStaID))
            {
                panelPLCRunInfo.Visible = true;
                if (tPLCStation != null)
                {
                    try
                    {
                        textBoxStation.Text = tCurrentStaID;

                        buttonOpenPLC.Text = ((StationPLCType)tPLCStation.StationType).ToString();
                        labelPLCRegStar.Text = tPLCStation.StationRegStar.ToString();
                        labelPLCRegCount.Text = tPLCStation.StationRegCount.ToString();
                        labelLastAction.Text = tPLCStation.LastActiveTime.ToString("HH:mm:ss.fff");
                        List<ushort> tHexRegValues = new List<ushort>(tPLCStation.RegValues);
                        if (listViewRegValue.Items.Count != tHexRegValues.Count)
                        {
                            listViewRegValue.Items.Clear();
                            for (int i = 0; i < tHexRegValues.Count; i++)
                            {
                                ListViewItem tItem = new ListViewItem((i + tPLCStation.StationRegStar).ToString());
                                tItem.SubItems.Add(string.Format("0x{0:X2}", i + tPLCStation.StationRegStar));
                                tItem.SubItems.Add(tHexRegValues[i].ToString());
                                tItem.SubItems.Add(string.Format("0x{0:X4}", tHexRegValues[i]));
                                listViewRegValue.Items.Add(tItem);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < tHexRegValues.Count; i++)
                            {
                                ListViewItem tItem = listViewRegValue.Items[i];
                                tItem.SubItems[2].Text = tHexRegValues[i].ToString();

                                tItem.SubItems[3].Text = string.Format("0x{0:X4}", tHexRegValues[i]);
                            }
                        }
                    }
                    finally
                    {
                    }
                }
            }
            else
            {
                panelPLCRunInfo.Visible = false;
            }

        }

        private void FDatasClient_FormClosed(object sender, FormClosedEventArgs e)
        {
            tThdReadPLCInfoRun = false;
            if (tThdReadPLCInfo != null)
                tThdReadPLCInfo = null;
        }

        private void listViewStationList_MouseClick(object sender, MouseEventArgs e)
        {
            tCurrentStaID = "";
            if (listViewStationList.SelectedItems.Count > 0)
            {
                ListViewItem tSelItem = listViewStationList.SelectedItems[0];
                if (tSelItem != null)
                {
                    tCurrentStaID = tSelItem.Text;
                    if (tThdReadPLCInfo == null)
                    {
                        tThdReadPLCInfo = new Thread(tMainThd);
                        tThdReadPLCInfoRun = true;
                        tThdReadPLCInfo.Start();
                    }
                }
            }
        }

        Thread tThdReadPLCInfo = null;
        bool tThdReadPLCInfoRun = false;
        private void tMainThd()
        {
            while (tThdReadPLCInfoRun)
                try
                {
                    IPEndPoint destEP = new IPEndPoint(IPAddress.Parse(textBoxAPISerIP.Text), (int)numericUpDownAPISerPort.Value);

                    if (!string.IsNullOrEmpty(tCurrentStaID))
                    {
                        lastCommand = new Dictionary<string, string>();
                        lastCommand.Add(Command_GetStationRunInfo, tCurrentStaID);
                        byte[] tBuf = getComamndBytes(lastCommand);
                        TCPClientAsync.SendWithCallBack(destEP, tBuf, GetStationRunInfo_OnReceiveRespon, 500);
                    }
                    else
                        break;
                }
                finally
                {
                    Thread.Sleep(100);
                }
            tThdReadPLCInfo = null;
        }

        private PLCStation tPLCStation { get; set; } = null;
        /// <summary>
        ///  请求指定StationID的运行数据后的应答处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="RecData"></param>
        private void GetStationRunInfo_OnReceiveRespon(object sender, byte[] RecData)
        {
            Dictionary<string, object> tRespons = null;
            if ((RecData != null) && (RecData.Length > 0))
            {
                string sInfo = "";
                try
                {
                    sInfo = Encoding.UTF8.GetString(RecData);
                    if ((!string.IsNullOrEmpty(sInfo)) && sInfo.StartsWith("{") && sInfo.EndsWith("}"))
                        tRespons = JsonConvert.DeserializeObject<Dictionary<string, object>>(sInfo);
                }
                catch (Exception ex)
                {
                }
            }
            if ((!string.IsNullOrEmpty(tCurrentStaID)) && (tRespons != null))
            {
                if (tRespons.ContainsKey("err") && tRespons.ContainsKey("msg") && tRespons["msg"].Equals("ok")
                    && tRespons["err"].ToString().Equals("0") && tRespons.ContainsKey("StaRunInfo"))
                {
                    Dictionary<string, object> tThdResult = getJSONDictionaryByObject(tRespons["StaRunInfo"]);

                    int iStationType = 0;
                    int iRegStar = 0;
                    int iRegCount = 0;

                    if (tThdResult.ContainsKey("StationType") && int.TryParse(tThdResult["StationType"].ToString(), out iStationType)
                               && (iStationType >= 0))
                        if (tThdResult.ContainsKey("StationRegStar") && int.TryParse(tThdResult["StationRegStar"].ToString(), out iRegStar)
                                   && (iRegStar >= 0))
                            if (tThdResult.ContainsKey("StationRegCount") && int.TryParse(tThdResult["StationRegCount"].ToString(), out iRegCount)
                                       && (iRegCount >= 0))
                            {
                                if ((tPLCStation == null) || ((tPLCStation != null) && (!tPLCStation.StaID.Equals(tCurrentStaID))))
                                {
                                    tPLCStation = new PLCStation(tCurrentStaID, iRegCount, iRegStar);
                                    tPLCStation.StationType = iStationType;
                                }
                                string sLastActive = "";
                                if (tThdResult.ContainsKey("LastActiveTime"))
                                    sLastActive = tThdResult["LastActiveTime"].ToString();
                                if (tThdResult.ContainsKey("RegValues") && (tPLCStation != null))
                                {
                                    string sRegValues = tThdResult["RegValues"].ToString();
                                    List<object> tRegValues = JsonConvert.DeserializeObject<List<object>>(sRegValues);
                                    List<ushort> tHexRegValues = new List<ushort>();
                                    if (iRegCount == tRegValues.Count)
                                    {
                                        for (int i = 0; i < tRegValues.Count; i++)
                                        {
                                            ushort iValue = 0;
                                            if (ushort.TryParse(tRegValues[i].ToString(), out iValue))
                                            {
                                                tHexRegValues.Add(iValue);
                                            }
                                        }
                                    }
                                    tPLCStation.reFlashRegValues(iRegStar, tHexRegValues.ToArray(), sLastActive);
                                }
                            }
                }
            }
        }       

        private void buttonOpenPLC_Click(object sender, EventArgs e)
        {
            if (tPLCStation != null)
            {
                if ((StationPLCType)tPLCStation.StationType == StationPLCType.ADP2203VX)
                {
                    FPLCInfo_ADP2203VX tFPLCInfoADP2203VX = new FPLCInfo_ADP2203VX(new Station_ADP2203VX(tPLCStation));
                    tFPLCInfoADP2203VX.ShowDialog();
                }
                if ((StationPLCType)tPLCStation.StationType == StationPLCType.WFDRVX)
                {
                    FPLCInfo_WFDRVX tFPLCInfoWFDRVX = new FPLCInfo_WFDRVX(new Station_WFDRVX(tPLCStation));
                    tFPLCInfoWFDRVX.ShowDialog();
                }
            }
        }

    }
}
